package com.sgcc.epri.dcloud.service.impl;

import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sgcc.epri.dcloud.mapper.dm.AssetTypeParamCenterMapper;
import com.sgcc.epri.dcloud.mapper.dm.IndexIdCenterMapper;
import com.sgcc.epri.dcloud.mapper.dm.TableHeadMapper;
import com.sgcc.epri.dcloud.pojo.AssetTypeParamCenter;
import com.sgcc.epri.dcloud.pojo.Result;
import com.sgcc.epri.dcloud.pojo.TableHead;
import com.sgcc.epri.dcloud.service.TableHeadService;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.CompletableFuture;

@Service
public class TableHeadServiceImpl implements TableHeadService {

    private final Logger log =  LoggerFactory.getLogger(this.getClass());

    @Autowired
    private TableHeadMapper tableHeadMapper;

    @Autowired
    private ThreadPoolTaskExecutor threadPoolExecutor;

    @Override
    public Result queryObjects(String dataType) {
        try{
            if(dataType.equals("dky")){
                return Result.success(tableHeadMapper.queryObjects());
            } else if (dataType.equals("nr")) {
                return Result.success(tableHeadMapper.queryObjectNr());
            } else {
                return Result.success("请输入正确的参数！");
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error("查询对象类型"+e);
            return Result.error("查询对象类型失败");
        }
    }

    @Override
    public Result insertOne(String treeId, String dataType) {
        try{
            TableHead tableHead = new TableHead();
            tableHead.setParentIdTree(treeId);
            tableHead.setDataType(dataType);
            tableHead.setSort(NumberUtil.generateRandomNumber(1, 99999, 1)[0]+"");
            return Result.success(tableHeadMapper.insert(tableHead));
        }catch (Exception e){
            e.printStackTrace();
            log.error("新增一行失败!"+e);
            return Result.error("新增一行失败");
        }
    }

    @Override
    public Result update(TableHead tableHead) {
        try {
            TableHead byId = tableHeadMapper.selectOne(new QueryWrapper<TableHead>().eq("id", tableHead.getId()));
            QueryWrapper<TableHead> thqwbid = new QueryWrapper<>();
            thqwbid.eq("parent_id_tree", byId.getParentIdTree());
            thqwbid.eq("object_id", tableHead.getObjectId());
            List<TableHead> tableHeads = tableHeadMapper.selectList(thqwbid);
            if (tableHeads.size() > 0 && tableHead.getHiddenFlag() == null) {
                return Result.error("该表头已存在，请重新输入！");
            }else{
                if(tableHead.getHiddenFlag() == null || tableHead.getHiddenFlag().equals("")){
                    tableHead.setHiddenFlag("1");
                }
            }
            return Result.success(tableHeadMapper.updateById(tableHead));
        }catch (Exception e){
            e.printStackTrace();
            log.error("更新失败!"+e);
            return Result.error("更新失败");
        }
    }

    @Override
    public Result queryIndex(String dataType) {
        try{
            return Result.success(tableHeadMapper.queryIndexAll(dataType));
        }catch (Exception e){
            e.printStackTrace();
            log.error("查询指标失败"+e);
            return Result.error("查询指标失败");
        }
    }

    @Override
    public Result queryAssetByObjectId(String objectId, String dataType, Integer page, Integer limit, String key, String assetType) {
        try{

            if(dataType.equals("dky")){
                PageHelper.startPage(page, limit);
                List<String> ids = Arrays.asList(key.split(","));
                List<Map<String, Object>> maps = null;
                if(ids.size() > 1){
                    maps = tableHeadMapper.queryAssetByObjectIdList(objectId, ids, assetType);
                }else {
                    maps = tableHeadMapper.queryAssetByObjectId(objectId, key, assetType);
                }
                PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(maps);
                return Result.success(pageInfo);
            } else if (dataType.equals("nr")) {
                PageHelper.startPage(page, limit);
                List<Map<String, Object>> maps = tableHeadMapper.queryAssetByObjectIdNr(objectId, key);
                PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(maps);
                return Result.success(pageInfo);
            } else {
                return Result.success("请输入正确的参数！");
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error("查询资产类型失败!"+e);
            return Result.error("查询资产类型失败");
        }
    }

    @Autowired
    @Qualifier("dmSqlSessionFactory")
    private SqlSessionFactory sqlSessionFactory;

    @Autowired
    private AssetTypeParamCenterMapper assetTypeParamCenterMapper;

    @Transactional
    @Override
    public Result updateDifficulty(String type,String tableHeadId,String string, String dataType, String indexId) {

        String[] split = string.split(",");

        List<String> strings = Arrays.asList(split);

        // 关闭session的自动提交
        SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false);

        TableHeadMapper tableHeadMapper = sqlSession.getMapper(TableHeadMapper.class);
        try{

            if (type.equals("101")) {

                // 删除表头与指标中间表数据
                tableHeadMapper.deleteIndexMiddle(tableHeadId);
                // 批量插入
                strings.forEach(id -> tableHeadMapper.saveIndexs(tableHeadId, id));

                // 后台为该表头修改指标名
                threadPoolExecutor.execute(() -> {
                    CompletableFuture<String> qinbi = queryIndexNameByIds(strings);
                    TableHead tableHead = new TableHead();
                    tableHead.setId(Long.parseLong(tableHeadId));
                    try {
                        tableHead.setIndexNames(qinbi.get());
                    } catch (Exception e) {
                        e.printStackTrace();
                        log.error("修改指标名错误！");
                    }
                    this.tableHeadMapper.updateById(tableHead);

                });

            } else if (type.equals("102")) {
                tableHeadMapper.deleteAssetTypesIndex(tableHeadId, indexId);
                strings.forEach(id -> tableHeadMapper.saveAssetTypes(tableHeadId, id, indexId));

                // 后台为该表头修改资产名简写及统计资产类别
                threadPoolExecutor.execute(() -> {

                    QueryWrapper<AssetTypeParamCenter> apcq = new QueryWrapper<>(); // 取该表头相关的所有配置
                    apcq.eq("tablehead_id", tableHeadId);
                    apcq.select("WM_CONCAT(ASSET_ID) AS ASSET_ID");
                    AssetTypeParamCenter assetTypeParamCenter = this.assetTypeParamCenterMapper.selectOne(apcq);
                    log.info("查询结果："+assetTypeParamCenter.toString());
                    if (assetTypeParamCenter == null) {
                        assetTypeParamCenter = new AssetTypeParamCenter();
                        assetTypeParamCenter.setAssetId("");
                    }
                    String[] split1 = assetTypeParamCenter.getAssetId().split(",");
                    List<String> strings1 = Arrays.asList(split1);
                    log.info("处理结果："+strings1.size());
                    CompletableFuture<String> qabi = queryAssetNameByAssetId(strings1, dataType);
                    CompletableFuture<String> qanati = queryAssetNameByAssetTypeId(strings1, dataType);

                    CompletableFuture.allOf(qabi, qanati).join();

                    TableHead tableHead = new TableHead();
                    tableHead.setId(Long.parseLong(tableHeadId));
                    try {
                        tableHead.setAssetTypeNames(qanati.get() == null ? "" : qanati.get());
                        tableHead.setAssetNames(qabi.get() == null ? "" : qabi.get());
                    } catch (Exception e) {
                        e.printStackTrace();
                        log.error("修改资产名错误！");
                    }

                    this.tableHeadMapper.updateById(tableHead);
                });

            }

            // 提交数据
            sqlSession.commit();

            return Result.success("操作成功(资产类别将在稍后更新...)");
        }catch (Exception e){
            sqlSession.rollback();
            e.printStackTrace();
            log.error("修改时出错!"+e);
            return Result.error("修改时出错!");
        }finally {
            sqlSession.close();
        }
    }

    @Transactional
    @Override
    public Result upOrDown(String hostId, String rmId) {
        try{

            CompletableFuture<TableHead> hostFuture = querySortById(hostId);
            CompletableFuture<TableHead> rmFuture = querySortById(rmId);

            // 等待sql执行
            CompletableFuture.allOf(hostFuture, rmFuture).join();

            if(hostFuture.get() == null || rmFuture.get() == null) return Result.error("参数有误");

            QueryWrapper<TableHead> muqwHost = new QueryWrapper<>();
            muqwHost.eq("id", hostId);
            TableHead hostTableHead = new TableHead();
            hostTableHead.setSort(rmFuture.get().getSort());
            tableHeadMapper.update(hostTableHead, muqwHost);

            QueryWrapper<TableHead> muqwRm = new QueryWrapper<>();
            muqwRm.eq("id", rmId);
            TableHead rmTableHead = new TableHead();
            rmTableHead.setSort(hostFuture.get().getSort());
            tableHeadMapper.update(rmTableHead, muqwRm);

            return Result.success("修改成功");
        }catch (Exception e){
            e.printStackTrace();
            log.error("修改失败"+e);
            return Result.error("修改失败");
        }
    }

    @Override
    @Async("threadPoolTaskExecutor")
    public void deleteTableHead(String tableHeadId) {
        try{
            tableHeadMapper.deleteById(tableHeadId);
            tableHeadMapper.deleteIndexMiddle(tableHeadId);
            tableHeadMapper.deleteAssetTypes(tableHeadId);
            tableHeadMapper.deleteCalResult(tableHeadId);
            tableHeadMapper.deleteAllContent(tableHeadId);
        }catch (Exception e){
            e.printStackTrace();
            log.error("删除失败!");
        }
    }

    @Override
    public Result queryTableHead(String treeId, String dataType, Integer page, Integer limit) {
        try{
            Page<TableHead> pl = new Page<>(page, limit);
            QueryWrapper<TableHead> oqw = new QueryWrapper<>();
            oqw.eq("parent_id_tree",treeId);
            oqw.eq("data_type", dataType);
            oqw.orderByAsc("sort");
            Page<TableHead> tableHeadPage = tableHeadMapper.selectPage(pl, oqw);
            return Result.success(tableHeadPage);
        }catch (Exception e){
            e.printStackTrace();
            log.error("查询表头失败!"+e);
            return Result.error("查询表头失败");
        }
    }

    @Override
    public Result queryParamContent(String tableHeadId, String type, String dataType, String indexId, String objectId) {
        try{

            if (type.equals("101")) {
                return Result.success(tableHeadMapper.queryIndexByType(tableHeadId));
            } else if (type.equals("102")) {
                if (dataType.equals("dky")) {
                    return Result.success(tableHeadMapper.queryAssetByType(tableHeadId, indexId));
                } else if (dataType.equals("nr")) {
                    return Result.success(tableHeadMapper.queryAssetByTypeNr(tableHeadId, indexId, objectId));
                }
            }

        }catch (Exception e){
            e.printStackTrace();
            log.error("查询表头配置详情失败!"+e);
            return Result.error("查询表头配置详情失败");
        }
        return null;
    }

    @Transactional
    @Override
    public Result conventionalConfiguration(String currentTreeId, String targetTreeId, String dataType) {

        // 在执行以下操作前，清除当前树某个维度(dky or nr)所有表头相关的一切配置。
        QueryWrapper<TableHead> thqwD = new QueryWrapper<>();
        thqwD.eq("parent_id_tree",currentTreeId);
        thqwD.eq("data_type", dataType);
        List<TableHead> tableHeadsD = tableHeadMapper.selectList(thqwD);
        tableHeadsD.forEach(th -> deleteTableHead(th.getId()+""));

        // 关闭session的自动提交
        SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false);
        TableHeadMapper tableHeadMapper = sqlSession.getMapper(TableHeadMapper.class);

        try{

            // 被复制树的相关表头
            QueryWrapper<TableHead> thqw = new QueryWrapper<>();
            thqw.eq("parent_id_tree", targetTreeId);
            thqw.eq("data_type", dataType);
            List<TableHead> tableHeads = tableHeadMapper.selectList(thqw);
            // 被复制树相关表头的相关表头及指标和参数  复制到 要复制树相关表头的相关表头及指标和参数
            tableHeads.forEach(th -> {

                Result result = queryCurrentTableIndex(th.getId() + "");

                String thId = th.getId()+"";

                // 清除id
                th.setId(null);
                // 重新设置表头的树形结构id
                th.setParentIdTree(currentTreeId);
                // 复制表头 使得重新设置id
                tableHeadMapper.insert(th);

                List<Map<String, Object>> data = (List<Map<String, Object>>) result.getData();
                for (Map<String, Object> datum : data) {
                    String indexId = datum.get("id").toString();

                    String objectId = "";
                    if (dataType.equals("nr")) {
                        QueryWrapper<TableHead> thqwO = new QueryWrapper<>();
                        thqwO.select("object_id");
                        thqwO.eq("id", th.getId());
                        TableHead tableHead = tableHeadMapper.selectOne(thqwO);
                        objectId = tableHead.getObjectId();
                    }

                    Result resultI = queryParamContent(thId + "", "101", dataType, indexId, objectId);
                    Result resultP = queryParamContent(thId + "", "102", dataType, indexId, objectId);

                    List<Map<String, Object>> dataI = new ArrayList<Map<String, Object>>();
                    if (resultI.getData() != null) {
                        dataI = (List<Map<String, Object>>) resultI.getData();
                    }
                    List<Map<String, Object>> dataP = new ArrayList<Map<String, Object>>();
                    if (resultP.getData() != null) {
                        dataP = (List<Map<String, Object>>) resultP.getData();
                    }

                    String idsI = "";
                    String idsP = "";
                    for (Map<String, Object> map : dataI) {
                        idsI += "," + map.get("id");
                    }
                    if(!"".equals(idsI))idsI = idsI.substring(1);
                    for (Map<String, Object> map : dataP) {
                        idsP += "," + map.get("id");
                    }
                    if(!"".equals(idsP))idsP = idsP.substring(1);

                    if (!idsI.toString().equals("")) {
                        updateDifficulty("101", th.getId() + "", idsI, dataType, indexId);
                    }
                    if (!idsP.toString().equals("")) {
                        updateDifficulty("102", th.getId() + "", idsP, dataType, indexId);
                    }
                }
            });

            // 提交数据
            sqlSession.commit();
            return Result.success("复制成功");
        }catch (Exception e){
            e.printStackTrace();
            log.error("复制过程中出错!"+e);
            return Result.error("复制过程中出错!");
        }finally {
            sqlSession.close();
        }
    }

    @Override
    public Result queryAssetType(String dataType) {
        try{
            if (dataType.equals("dky")) {
                return Result.success(tableHeadMapper.queryAssetType());
            } else if (dataType.equals("nr")) {
                List<Map<String, Object>> mapList = new ArrayList<>();
                Map<String, Object> map = new HashMap<>();
                map.put("id", "0202");
                map.put("name", "电量");
                mapList.add(map);
                return Result.success(mapList);
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error("查询资产类别失败!"+e);
        }
        return Result.error("查询资产类别失败");
    }

    @Autowired
    private IndexIdCenterMapper indexIdCenterMapper;

    @Override
    public Result queryCurrentTableIndex(String tableHeadId) {
        try{
            return Result.success(indexIdCenterMapper.queryCurrentTableIndex(tableHeadId));
        }catch (Exception e){
            e.printStackTrace();
            log.error("查询当前表头配置的指标出错!"+e);
        }
        return Result.error("查询当前表头配置的指标出错");
    }

    @Override
    public Result copyIndexParam(String type, String tableHeadId, String dataType, String indexIdMe, String indexIdHim) {

        try{
            Result result = queryParamContent(tableHeadId, type, dataType, indexIdHim, null);

            List<Map<String, Object>> data = (List<Map<String, Object>>) result.getData();

            String ids = "";
            for (Map<String, Object> datum : data) {
                ids += "," + datum.get("id");
            }
            ids = ids.substring(1);

            updateDifficulty(type, tableHeadId, ids, dataType, indexIdMe);
            return Result.success("复制成功");
        }catch (Exception e){
            e.printStackTrace();
            log.error("复制过程中出错");
            return Result.error("复制过程中出错");
        }
    }

    @Async("threadPoolTaskExecutor")
    public CompletableFuture<TableHead> querySortById(String id){
        try{
            QueryWrapper<TableHead> oqw = new QueryWrapper<>();
            oqw.eq("id",id);
            return CompletableFuture.completedFuture(tableHeadMapper.selectOne(oqw));
        }catch (Exception e){
            e.printStackTrace();
            log.error("Error executing SQL query: {}", e);
            return null;
        }
    }

    @Async("threadPoolTaskExecutor")
    public CompletableFuture<String> queryAssetNameByAssetId(List<String> list, String dataType){
        try{
            if(dataType.equals("dky")){
                return CompletableFuture.completedFuture(tableHeadMapper.queryAssetNameByAssetId(list));
            } else if (dataType.equals("nr")) {
                return CompletableFuture.completedFuture(tableHeadMapper.queryAssetNameByAssetIdNr(list));
            } else {
                return CompletableFuture.completedFuture("请输入正确的参数");
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error("Error executing SQL query: {}", e);
            return null;
        }
    }

    @Async("threadPoolTaskExecutor")
    public CompletableFuture<String> queryAssetNameByAssetTypeId(List<String> list, String dataType){
        try{
            if(dataType.equals("dky")){
                return CompletableFuture.completedFuture(tableHeadMapper.queryAssetNameByAssetTypeId(list));
            } else if (dataType.equals("nr")) {
                return CompletableFuture.completedFuture("电量");
            } else {
                return CompletableFuture.completedFuture("请输入正确的参数");
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error("Error executing SQL query: {}", e);
            return null;
        }
    }

    @Async("threadPoolTaskExecutor")
    public CompletableFuture<String> queryIndexNameByIds(List<String> list){
        try{
            return CompletableFuture.completedFuture(tableHeadMapper.queryIndexNameByIds(list));
        }catch (Exception e){
            e.printStackTrace();
            log.error("Error executing SQL query: {}", e);
            return null;
        }
    }

}
